package com.mojo.redisson.controller;

import com.mojo.response.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
public class RedissonController {

    private final RedissonClient redissonClient;

    @Autowired
    public RedissonController(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    @GetMapping("/example")
    public String example() {
        // 获取分布式对象
        RBucket<String> bucket = redissonClient.getBucket("example");
        // 写入数据
        bucket.set("Hello Redisson!");

        // 读取数据
        return bucket.get();
    }

    @GetMapping("/redisson-lock")
    public ResultVO<?> redissonLock() {
        RLock lock = redissonClient.getLock("redisson-lock");
        // 设置锁过期时间，看门狗失效
        lock.lock(5, TimeUnit.SECONDS);

        // 看门狗生效
        //lock.lock();
        try {
            // 1、锁的自动续期，运行期间自动给锁续上新的30s，无需担心业务时间长，锁过期会自动被释放
            // 2、加锁的业务只要运行完成，就不会给当前锁续期，即使不手动释放锁，锁默认在30s后自动释放，避免死锁
            log.info("加锁成功，执行业务代码...{}", Thread.currentThread().getId());
            TimeUnit.SECONDS.sleep(11L);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("释放锁..." + Thread.currentThread().getId());
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                log.info("Unlocking lock for key {}", "redisson-lock");
                lock.unlock();
                log.info("Released lock for key {}", "redisson-lock");
            }
        }
        return ResultVO.success();
    }
}